<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Goods;
use App\Models\Product;
use Illuminate\Http\Request;

class GoodsController extends Controller
{
    function __construct()
    {
//        我在路由中已经设置了中间件认证,所以这里不需要再加验证了
//        $this->middleware('admin');
    }

    public function index()
    {
//        $categorys = Category::select('title')->get()->toArray();
        $goods = Goods::latest()->get();
        return view('admin.goods.index', compact('goods'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //获取所有顶级分类数据并分配到前台页面中去
        //前台页面根据用户选择的不同顶级分类,通过前台发送异步请求的方式获取相应一级分类下的二级三级分类信息
        $categorys = Category::where('parent_id', 0)->oldest()->get();
        //通过pluck方法可以直接以数组的形式返回模型对象集合中指定字段组成的数组
        $categoryList = Category::pluck('title','id');
//        dd($categoryList);
        return view('admin.goods.create', compact('categorys','categoryList'));
    }


    public function store(Request $request)
    {
//        dd($request->all());
        //集合中的all()方法可以返回集合表示的底层数组
        //也可以在控制器方法中写当前控制器方法的表单请求数据的验证
        $request->validate([
            'description' => 'required',
            'pics' => 'required',
            'category_id' => function ($attr, $value, $fail) {
                if (in_array(null, $value)) {
                    return $fail('商品分类不能为空');
                }
//                栏目满足条件就返回true
                return true;
            }
        ],[
            'description.required'=>'描述不能为空',
            'pics.required'=>'商品图片不能为空',
        ]);
        //集合中的all()方法可以返回集合表示的底层数组
        //调用模型的create方法,创建新的模型对象
        //save 方法接受一个完整的 Eloquent 模型实例，而 create 则接受普通的 PHP 数组
        $good = Goods::create($request->all());
        //传递过来的$request->product 是一个json格式的前台对象数组,需要转换成php数组方便在php中进行后面的处理
        $products = json_decode($request->product, true);
        //向product表中创建数据
        //方式一:循环数组的方式
//        foreach ($products as $product){
//            $product['goods_id']=$good['id'];
//            Product::create($product);
//        };
        //方式二:可以通过模型关联的方式向product货品表中添加数据
        //$good是新创建的商品模型对象,通过这个模型对象调用商品模型中的模型关联方法创建数据,由于这里的模型关联是一对多关联所以这里使用createMany()方法在关联表中创建关联数据.(注意这里通过模型关联的方式创建数据的时候就不需再在products表中添加goods_id字段了,通过模型关联的方式laravel会自动处理)
        $good->product()->createMany($products);
        return redirect(route('admin.goods.create'))->with('success', '商品创建成功');
    }


    public function show(Goods $goods)
    {
        //
    }


    public function edit(Goods $good)
    {


//        由于编辑货品的时候只需要'attrs','kucun','addPrice'这三个属性,通过下面的处理就可以只保留需要的属性
        // php只提供了array_only()函数可以从一个数组中返回指定的键值对,但是这里是多维数组不能直接使用array_only()方法,一种思路是继续找看有没有别的方法,另外一条思路就是要想办法把多维数组分成一个一个单独的数组,这样就能使用array_only()方法了
        //调用goods对象中的模型关联方法,获取当前商品对应的货品信息(通过模型关联的动态属性方式)
        $products = $good->product->map(function ($value) {
            return array_only($value->toArray(), ['attrs', 'kucun', 'addPrice']);
        });
        //这里还有个细节需要注意goods对象通过模型关联方法product()的动态属性product获取goods表关联的货品表对象,但是""如果货品表中没有与goods相关联的数据时,返回的是一个空数组""
//        对于上面的问题其实也没必要那么麻烦直接使用查询构造器的select方法指定要取哪些字段也可以达到目的
//        $good->select('title','price');
//        获取所有的顶级分类数据
        $oneCategorys = Category::where('parent_id', 0)->get();
//        获取当前商品所在二级分类的信息
        $twoCategorys = Category::where('parent_id', $good['category_id'][0])->get();
//        获取当前商品所在三级分类的信息
        $threeCategorys = Category::where('parent_id', $good['category_id'][1])->get();
//        dd([$oneCategorys,$twoCategorys,$threeCategorys]);
        return view('admin.goods.edit', compact('good', 'products', 'oneCategorys', 'twoCategorys', 'threeCategorys'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \App\Models\Goods $goods
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Goods $good)
    {
//        dd($request->all());
        //调用模型对象的update方法,更新数据
        $good->update($request->all());
        //先通过模型关联删除掉相应的货品表
        $good->product()->delete();
        //然后通过模型关联的方式创建货品数据
        $products = json_decode($good->product, true);
        //通过模型关联的方式向product产品表中创建模型对象.由于goods表和product表是一对多的关系,所以要用createMany()创建模型对象
        $good->product()->createMany($products);
        return redirect(route('admin.goods.index'))->with('success', '商品编辑成功');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Goods $goods
     * @return \Illuminate\Http\Response
     */
    public function destroy(Goods $good)
    {
        //调用模型对象的delete方法,删除模型
        //由于货品表和商品表在mysql数据库上做了模型关联,所以删除商品表中的数据后mysql数据库会自动将货品表中相对应的数据删除
        $good->delete();
        return redirect(route('admin.goods.index'))->with('success', '商品删除成功');
    }
}
